package cn.yunbamboos.media.core;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.media.zlm.ZLMClientList;
import cn.yunbamboos.media.zlm.api.ZLMApi;
import cn.yunbamboos.media.zlm.client.ZLMClient;
import cn.yunbamboos.media.zlm.client.param.AddFFmpegSourceApiParams;
import cn.yunbamboos.media.zlm.client.param.AddStreamProxyApiParams;
import cn.yunbamboos.media.zlm.client.result.IResult;
import cn.yunbamboos.media.zlm.client.result.data.AddFFmpegSourceResultData;
import cn.yunbamboos.media.zlm.client.result.data.AddStreamProxyResultData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class MediaService {

    private static final Logger logger = LoggerFactory.getLogger(MediaService.class);

    private final ApplicationContext applicationContext;
    private final ZLMClientList clientList;

    public MediaService(ApplicationContext applicationContext, ZLMClientList clientList) {
        this.applicationContext = applicationContext;
        this.clientList = clientList;
    }

    public boolean play(String mediaServerId, String app, String stream) {
        // 查找播放连接
        ICreatePlayProxy createPlayProxy = applicationContext.getBean(ICreatePlayProxy.class);
        if (ObjUtil.isNull(createPlayProxy)) {
            logger.warn("[ZLM {}] app: {} stream: {} 获取播放连接失败", mediaServerId, app, stream);
            return false;
        }
        Optional<PlayProxy> playProxyOptional = createPlayProxy.create(mediaServerId, app, stream);
        if (playProxyOptional.isEmpty()) {
            logger.warn("[ZLM {}] app: {} stream: {} 创建取播放代理失败", mediaServerId, app, stream);
            return false;
        }
        PlayProxy playProxy = playProxyOptional.get();
        Optional<ZLMClient> optional = clientList.get(mediaServerId);
        if (optional.isEmpty()) {
            logger.warn("[ZLM {}] app: {} stream: {} 获取播放客户端失败", mediaServerId, app, stream);
            return false;
        }
        ZLMClient client = optional.get();
        ZLMApi api = client.getApi();
        // 判断播放地址类型
        if (playProxy.isLocalFile()) {
            String url = playProxy.getUrl();
            String dstUrl = StrUtil.format("rtmp://{}:{}/{}/{}", client.getIp(), client.getRtmpPort(), app, stream);
            AddFFmpegSourceApiParams params = new AddFFmpegSourceApiParams().setSrcUrl(url).setDstUrl(dstUrl);
            IResult<AddFFmpegSourceResultData> result = api.addFFmpegSource(params);
            if (result.isSuccess()) {
                AddFFmpegSourceResultData data = result.getData();
                logger.info("{}", data.getKey());
                // 播放成功 添加到代理容器
                return true;
            }
            logger.warn("[ZLM {}] addFFmpegSource app: {} stream: {} {}", mediaServerId, app, stream, result.getMsg());
        } else {
            String url = playProxy.getUrl();
            AddStreamProxyApiParams params = new AddStreamProxyApiParams().setApp(app).setStream(stream).setUrl(url);
            IResult<AddStreamProxyResultData> result = api.addStreamProxy(params);
            if (result.isSuccess()) {
                AddStreamProxyResultData data = result.getData();
                logger.info("{}", data.getKey());
                // 播放成功 添加到代理容器
                return true;
            }
            logger.warn("[ZLM {}] addStreamProxy app: {} stream: {} {}", mediaServerId, app, stream, result.getMsg());
        }
        logger.warn("[ZLM {}] app: {} stream: {} 播放失败", mediaServerId, app, stream);
        return false;
    }


    public Map<String, String> getPlayUrl(String mediaServerId, String app, String stream) {
        Map<String, String> result = new HashMap<>();
        Optional<ZLMClient> optional = clientList.get(mediaServerId);
        if (optional.isEmpty()) {
            logger.warn("[ZLM {}] 获取播放客户端失败", mediaServerId);
            return result;
        }
        ZLMClient client = optional.get();
        result.put("RTSP", StrUtil.format("rtsp://{}:{}/{}/{}", client.getIp(), client.getRtspPort(), app, stream));
        result.put("RTMP", StrUtil.format("rtmp://{}:{}/{}/{}", client.getIp(), client.getRtmpPort(), app, stream));
        result.put("HTTP-FLV", StrUtil.format("http://{}:{}/{}/{}.live.flv", client.getIp(), client.getPort(), app, stream));
        result.put("WS-FLV", StrUtil.format("ws://{}:{}/{}/{}.live.flv", client.getIp(), client.getPort(), app, stream));
        result.put("HLS", StrUtil.format("http://{}:{}/{}/{}/hls.m3u8", client.getIp(), client.getPort(), app, stream));
        result.put("HTTP-TS", StrUtil.format("http://{}:{}/{}/{}.live.ts", client.getIp(), client.getPort(), app, stream));
        result.put("WS-TS", StrUtil.format("ws://{}:{}/{}/{}.live.ts", client.getIp(), client.getPort(), app, stream));
        result.put("HTTP-FMP4", StrUtil.format("http://{}:{}/{}/{}.live.mp4", client.getIp(), client.getPort(), app, stream));
        result.put("WS-FMP4", StrUtil.format("ws://{}:{}/{}/{}.live.mp4", client.getIp(), client.getPort(), app, stream));
        return result;
    }

}
